

#include <pio.h>

/**
 * Loads the initial enviroment data for the simulation from the specified
 * file.
 */
llist_t *physm_load_data(char *file, int print_err, int *err){

  /* Open the file: */
  FILE *env_file = fopen(file, "r");

  if (env_file == NULL){
    (*err) = 1;
    if (print_err){
      fprintf(stderr, "[physm-load-file] Error opening file: %s\n", file);
    }
    return NULL;
  }

  (*err) = 0;
  return _physm_io_do_load(env_file, print_err, err);

}

/**
 * Go through the file, line by line and parse it.
 */
llist_t *_physm_io_do_load(FILE *env_file, int print_err, int *err){

  char buf[128];
  llist_t *list = PHYSM_ALLOC_LLIST();
  physm_llist_init(list);

  while (1){
    memset(buf, 0, 128);
    if (fgets(buf, 128, env_file)){
      int ok;
      physm_body_t *body = _physm_io_parse_body(buf, print_err, &ok);
      if (ok != 0){
	if (print_err){
	  fprintf(stderr, "[physm-load-file] Error parsing body.\n");
	}
	(*err) = 1;
	return list;
      }
      if (body != NULL){
	//_physm_body_print(body);
	physm_llist_add(list, body);
      }
    } else {
      /* We are done with the file. */
      fclose(env_file);
      (*err) = 0;
      return list;
    }
  }

  return NULL; // Makes the compiler happy.

}

int _physm_blank_str(char *str){

  int i;
  for ( i = 0; i < strlen(str); i++){
    if (!isspace(str[i])) return 1;
  }
  return 0;

}

void _physm_cut_comment(char *str){

  int i = 0;
  for ( ; i < strlen(str) - 1; i++){
    if (str[i] == '/' && str[i+1] == '/'){
      str[i] = 0;
      str[i+1] = 0;
    }
  }

}

physm_body_t *_physm_io_parse_body(char *line, int print_err, int *err){

  _physm_cut_comment(line);

  if (_physm_blank_str(line)== 0){
    (*err) = 0;
    return NULL;
  }

  char *prefix = strtok(line, ":");
  if (strcmp(prefix, "body") != 0){
    (*err) = 1;
    if (print_err){
      fprintf(stderr, "[physm-load-file] %s%s\n", 
	      "Statement does not begin with recognized token: ",
	      prefix);
    }
    return NULL;
  }

  physm_body_t tmp;
  physm_body_init(&tmp);

  char *tok = strtok(NULL, " ");
  while (tok != NULL){

    char *var, *val = NULL;
    int i;
    var = tok;

    for ( i = 0; i < strlen(tok) - 1; i++){
      if (tok[i] == '='){
	tok[i] = 0;
	val = &tok[i+1];
	i = strlen(tok);
      }
    }

    if (val == NULL){
      if (print_err){
	fprintf(stderr, "[physm-load-file] %s\n", 
		"No equals sign found or no data after the equals.");
      }
      (*err) = 1;
      return NULL;
    }
    
    if(strcmp(var, "loc") == 0){
      if (!vm_sread(val, &tmp.loc)){
	if (print_err){
	  fprintf(stderr, "[physm-load-file] Error reading loc vector: %s\n", 
		  val);
	}
	(*err) = 1;
	return NULL;
      }
    } else if (strcmp(var, "vel") == 0){
      if (!vm_sread(val, &tmp.vel)){
	if (print_err){
	  fprintf(stderr, "[physm-load-file] Error reading vel vector: %s\n", 
		  val);
	}
	(*err) = 1;
	return NULL;
      }
    } else if (strcmp(var, "width") == 0){
      tmp.width = strtod(val, NULL);
    } else if (strcmp(var, "mass") == 0){
      tmp.mass = strtod(val, NULL);
    } else {
      if (print_err){
	fprintf(stderr, "[physm-load-file] %s%s\n", 
		"Unrecognized param to body initializer: ", var);
      }
      (*err) = 1;
      return NULL;
    }
    tok = strtok(NULL, " ");
  }
  
  //_physm_body_print(&tmp);
  physm_body_t *body = PHYSM_ALLOC_BODY();
  memcpy(body, &tmp, sizeof(physm_body_t));

  (*err) = 0;
  return body;

}
